package com.ddch.udpsocket.activity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.ddch.udpsocket.R;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity{
    private static final int CLIENT_PORT = 8000;
    private static final int SERVER_PORT = 3000;
    private byte bufClient[] = new byte[1024];
    private byte bufServer[] = new byte[1024];
    private static final int BUF_LENGTH = 1024;
    private DatagramSocket client;
    private DatagramPacket dpClientSend;
    private DatagramPacket dpClientReceive;
    private DatagramSocket server;
    private DatagramPacket dpServerReceive;
    private TextView tvClient;
    private TextView tvServer;
    private Thread threadServer;
    private Thread threadClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvClient = findViewById(R.id.tv_client);
        tvServer = findViewById(R.id.tv_server);
        createServer();
        createClient();
    }

    private void startClientThread() {
        // 创建用来发送的DatagramPacket数据报，其中应该包含要发送的信息，以及本机地址，目标端口号
        threadClient = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    byte[] sendData = createSendData("我是客户端消息");
                    InetAddress clientAddress = InetAddress.getLocalHost();
                    dpClientSend = new DatagramPacket(sendData,sendData.length,clientAddress,SERVER_PORT);
                    Log.d("liaoming", "threadClient ,inetAddress = " + clientAddress + " , port = " + SERVER_PORT);
                    client.send(dpClientSend);
                    while(true){
                        client.receive(dpClientReceive);
                        final String receiveData = createReceiveData(dpClientReceive);
                        tvClient.post(new Runnable() {
                            @Override
                            public void run() {
                                tvClient.setText(receiveData);
                            }
                        });

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });
        threadClient.start();
    }

    private void createClient() {
        try {
            // 创建客户端，并且指定端口号，在此端口号侦听信息
            client = new DatagramSocket(CLIENT_PORT);
            dpClientReceive = new DatagramPacket(bufClient, BUF_LENGTH);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    private void createServer() {
        try {
            server = new DatagramSocket(SERVER_PORT);
            dpServerReceive = new DatagramPacket(bufServer, BUF_LENGTH);
            startServerThread();
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    private void startServerThread() {
        threadServer = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    server.receive(dpServerReceive);
                    final String receiveData = createReceiveData(dpServerReceive);
                    tvServer.post(new Runnable() {
                        @Override
                        public void run() {
                            tvServer.setText(receiveData);
                            Log.d("liaoming", "threadServer ,tvServer = " + receiveData);
                        }
                    });
                    byte[] sendData = createSendData("我是服务端消息");

                    DatagramPacket dpServerSend = new DatagramPacket(sendData, sendData.length, dpServerReceive.getAddress(), dpServerReceive.getPort());
                 InetAddress inetAddress =   dpServerReceive.getAddress();
                    Log.d("liaoming", "threadServer ,inetAddress = " + inetAddress.getHostAddress() + " , port = " + dpServerReceive.getPort());
                    server.send(dpServerSend);
                    Log.d("liaoming", "threadServer ,server.send()" );
                    dpServerReceive.setLength(BUF_LENGTH);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        threadServer.start();
    }

    /**
     * 将中文字符转码发送
     * @param strSend
     * @return
     */
    private byte[] createSendData(String strSend) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dataOutputStream = new DataOutputStream(baos);
        try {
            dataOutputStream.writeUTF(strSend);
            dataOutputStream.close();
            return baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new byte[0];
    }

    /**
     * 将中文解码接收
     * @param dp
     * @return
     */
    private String createReceiveData(DatagramPacket dp) {
        try {
            DataInputStream stream = new DataInputStream(new ByteArrayInputStream(dp.getData(),dp.getOffset(),dp.getLength()));
            String msg = stream.readUTF();
            Log.i("liaoming", "createReceiveData = " +  msg);
            return msg;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public void send(View view) {
        if(view.getId() == R.id.bt_send){
            startClientThread();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        threadClient.interrupt();
        threadServer.interrupt();
        client.close();
        server.close();
    }
}
